import { Cell } from '@antv/x6';
import styled from '@emotion/styled';
import { Button, ConfigProvider, Dropdown, MenuProps, notification } from 'antd';
import classNames from 'classnames';

import { get, post } from '@/api';
import { FlowDeleteModal, FlowDeleteModalRef } from '@/components/complex/FlowDeleteModal';
import { colors } from '@/config/theme';
import { useGraph } from '@/hooks/useGraph';
import { useNodeResults } from '@/store/node-results';
import { emitter } from '@/utils/emitter';
import { formatEdgesForSave, formatNodesForSave, toDefaultCellStyle } from '@/utils/graph';

import { ActionOfSave, ActionsTestRef } from './save';
import { ActionsTest } from './test';

interface FlowActionsProps extends HTMLElementProps {
  onImportSuccess?: (graphJson: { cells: Cell.Properties[] }) => void;
}

const FlowActionsDiv = styled.div`
  border-bottom: 1px solid ${colors.gray['200']};
`;

export const FlowActions = memo<FlowActionsProps>((props) => {
  const [searchParams] = useSearchParams();
  const flowDeleteModalRef = useRef<FlowDeleteModalRef>(null);
  const flowId = searchParams.get('flowId') as any;
  const navigate = useNavigate();
  const { graph, saveGraph } = useGraph();
  const actionOfSaveRef = useRef<ActionsTestRef>(null);
  const { clearResults, hasExecResult } = useNodeResults();

  const exportHandle = useCallback(async () => {
    get('/flow/get', { flowId }).then((res) => {
      if (res) {
        const blob = new Blob([JSON.stringify(res, null, 2)], { type: 'application/json' });
        const a = document.createElement('a');
        a.download = res.flowName + '.json';
        a.href = URL.createObjectURL(blob);
        a.click();
      }
    });
  }, [flowId]);

  const importHandle = useCallback(async () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    input.onchange = async () => {
      const file = input.files![0];
      const reader = new FileReader();
      reader.onload = async (e) => {
        if (e.target) {
          const result = e.target.result as string;
          const json = JSON.parse(result);
          const graphJson = JSON.parse(json.graph || '{}') as {
            cells: Cell.Properties[];
          };

          await post('/flow/addGraph', {
            data: {
              flowId: Number(flowId),
              graph: json.graph,
              edges: formatEdgesForSave(graphJson.cells),
              nodes: formatNodesForSave(graphJson.cells)
            }
          }).then(() => {
            notification.success({
              message: '导入成功'
            });
            props.onImportSuccess?.(graphJson);
            setTimeout(() => {
              graph?.center();
            }, 300);
          });
        }
      };
      reader.readAsText(file);
    };
    input.click();
  }, [flowId, graph, props]);

  const moreMenu: MenuProps['items'] = useMemo(() => {
    return [
      {
        key: 'export',
        label: <div className="text-14 w-70">导出</div>,
        icon: <span className="i-solar:export-outline text-gray-500"></span>,
        onClick: exportHandle
      },
      {
        key: 'import',
        label: '导入',
        icon: <span className="i-solar:import-outline text-gray-500"></span>,
        onClick: importHandle
      },
      {
        key: 'delete',
        label: <span className="cursor-pointer text-red-500 text-14">删除</span>,
        icon: <span className="i-solar:trash-bin-minimalistic-linear text-red-500"></span>,
        onClick: () => {
          flowDeleteModalRef.current?.open();
        }
      }
    ];
  }, [exportHandle, importHandle]);

  const testOver = () => {
    clearResults();
    toDefaultCellStyle(graph);
  };

  return (
    <ConfigProvider componentDisabled={false}>
      <FlowActionsDiv className={classNames('flow-actions flex justify-between items-center h-50 pr-12', props.className)}>
        <div className="flow-actions-left">
          <span className="text-14--bold pl-12">流程编辑</span>
        </div>
        <div className="flow-actions-right flex gap-12 items-center">
          {hasExecResult ? (
            <Button type="primary" onClick={testOver}>
              <span className="i-solar:refresh-bold"></span>
              测试完成
            </Button>
          ) : (
            <>
              <ActionsTest beforeTest={() => actionOfSaveRef.current?.saveHandle(true, true)} />
              <Button type="primary">
                <span className="i-solar:documents-line-duotone"></span>生成文档
              </Button>
              <ActionOfSave ref={actionOfSaveRef} />
              <Dropdown menu={{ items: moreMenu }} arrow>
                <div className="flex gap-4 cursor-pointer text-14 text-primary-500 items-center">
                  更多
                  <span className="i-solar:menu-dots-bold text-primary-500"></span>
                </div>
              </Dropdown>
            </>
          )}
        </div>

        <FlowDeleteModal
          ref={flowDeleteModalRef}
          flowId={flowId}
          onSuccess={() => {
            navigate('/flow');
            emitter.emit('refresh-flow-list');
            graph?.clearCells();
            saveGraph();
          }}
        />
      </FlowActionsDiv>
    </ConfigProvider>
  );
});
